/**
 * 
 */
package optimization.naturalOptimization.population.individual.pso;

import math.VectorCalculations;
import optimization.naturalOptimization.particleSwarmOptimization.InertiaWeightPSO;
import optimization.naturalOptimization.population.Population;
import optimization.randomNumberGenerator.RandomNumberGenerator;

/**
 * Provides a particle for the inertia weight pso algorithm.
 * 
 * @author Kevin Wagner
 * @version 1.0
 */
public class DoubleArrayInertiaWeightPSOParticle extends DoubleArrayParticle {

	/**
	 * Creates a new Particle with the velocity update for the inertia weight
	 * PSO.
	 * 
	 * @param parentPopulation
	 */
	public DoubleArrayInertiaWeightPSOParticle(Population parentPopulation) {
		super(parentPopulation);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see optimization.naturalOptimization.population.individual.Particle#
	 * velocityUpdate()
	 */
	@Override
	protected void velocityUpdate() {
		RandomNumberGenerator generator = getParentPopulation()
				.getParentOptimization().getRng();
		InertiaWeightPSO pso = (InertiaWeightPSO) getParentPopulation()
				.getParentOptimization();
		try {
			double[] pbest = VectorCalculations.vectorSubtraction(
					getPersonalBest(), getPosition());
			for (int i = 0; i < pbest.length; i++) {
				pbest[i] *= generator.nextDouble() * pso.getC1();
			}
			double[] gbest = VectorCalculations.vectorSubtraction(
					getNeighborhoodBest(), getPosition());
			for (int i = 0; i < gbest.length; i++) {
				gbest[i] *= generator.nextDouble() * pso.getC2();
			}
			double[] newVel = VectorCalculations.vectorAddition(
					VectorCalculations.vectorAddition(gbest, pbest),
					VectorCalculations.vectorXNumber(getVelocity(),
							pso.getWeight()));
			setVelocity(newVel);
		} catch (Exception e) {
			getParentPopulation().getParentOptimization().pushError(e);
		}
	}

}
